package com.zy.openchat.core.model.video;

import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.text.TextUtils;

import com.zy.openchat.Constants;
import com.zy.openchat.core.model.message.VideoParam;
import com.zy.openchat.util.Common;
import com.zy.openchat.util.MediaUtils;
import com.zy.openchat.util.compress.VideoProcessor;
import com.zy.openchat.util.compress.util.VideoProgressListener;

import java.io.File;

public class UploadMedioInfo {

    public static final int DEFALT_WIDTH = 720;
    public static final int DEFALT_HEIGHT = 1280;
    public static final double DEFALT_RATE = DEFALT_WIDTH/Double.parseDouble(String.valueOf(DEFALT_HEIGHT));
    static final int COMPRESS_QUALITY_HIGH = 1;
    static final int COMPRESS_QUALITY_MEDIUM = 2;
    static final int COMPRESS_QUALITY_LOW = 3;

    public boolean isImage;

    public String mediaPath;

    public long duration;
    public int width;
    public int height;

    public float videoCompressProgress;
    public boolean isCompressFinish;

    public int index;
    public UploadMedioInfo withIndex(int index){
        this.index = index;
        return this;
    }

    public static UploadMedioInfo newVideoProgress(){
        UploadMedioInfo medioInfo = new UploadMedioInfo();
        medioInfo.isImage = false;
        medioInfo.videoCompressProgress = 0;
        medioInfo.isCompressFinish = false;
        return medioInfo;
    }

    public static UploadMedioInfo newImage(String path){
        UploadMedioInfo medioInfo = new UploadMedioInfo();
        medioInfo.isImage = true;
        medioInfo.mediaPath = path;
        return medioInfo;
    }

    public static UploadMedioInfo newVideo(String path, int width , int height, long duration){
        UploadMedioInfo medioInfo = new UploadMedioInfo();
        medioInfo.isImage = false;
        medioInfo.mediaPath = path;
        medioInfo.duration = duration;
        medioInfo.height = height;
        medioInfo.width = width;
        medioInfo.isCompressFinish = true;
        return medioInfo;
    }

    public static UploadMedioInfo newVideo(Context context,String localPah){
        VideoParam videoParam = MediaUtils.getVideoParam(localPah);
        return newVideo(localPah,videoParam.getWidth(),videoParam.getHeight(),videoParam==null?1000:videoParam.getDuration());
    }

    public static UploadMedioInfo compressVideo(Context context,String localPah){
        return compressVideo(context,localPah,null);
    }

    public static UploadMedioInfo compressVideo(Context context,String localPah,VideoProgressListener listener){
        VideoParam videoParam = MediaUtils.getVideoParam(localPah);
        String outputVideoPath = Constants.userVideoPath();
        File dir = new File(outputVideoPath);
        if(!dir.exists()){
            dir.mkdirs();
        }
        String houzhui = localPah.substring(localPah.lastIndexOf(".")+1,localPah.length());
        if(TextUtils.isEmpty(houzhui)){
            houzhui = "mp4";
        }
        String displayName = "video_compress_" + Common.getCurrentFormatTime() + "."+houzhui;
        outputVideoPath = outputVideoPath+displayName;
        int outWidth = videoParam==null?UploadMedioInfo.DEFALT_WIDTH:videoParam.getWidth();
        int outHeight = videoParam==null?UploadMedioInfo.DEFALT_HEIGHT:videoParam.getHeight();
        try {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(localPah);
            int originalWidth = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
            int originalHeight = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
            int originalBitrate = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
            int bitrate;
            int quality = COMPRESS_QUALITY_HIGH;
            switch (quality) {
                default:
                case COMPRESS_QUALITY_HIGH:
                    outWidth = originalWidth;
                    outHeight = originalHeight;
                    double whrate = originalWidth/Double.parseDouble(String.valueOf(originalHeight));
                    if(whrate<=DEFALT_RATE&&originalHeight>DEFALT_HEIGHT){
                        outHeight = DEFALT_HEIGHT;
                        outWidth = (int)Math.floor(DEFALT_HEIGHT*whrate);
                    }else if(whrate>DEFALT_RATE&&originalWidth > DEFALT_WIDTH){
                        outWidth = DEFALT_WIDTH;
                        outHeight = (int)Math.floor(DEFALT_WIDTH/whrate);
                    }
//                    bitrate = resultWidth * resultHeight * 30;
                    bitrate = originalBitrate;
                    break;
                case COMPRESS_QUALITY_MEDIUM:
                    outWidth = originalWidth / 2;
                    outHeight = originalHeight / 2;
                    bitrate = outWidth * outHeight * 10;
                    break;
                case COMPRESS_QUALITY_LOW:
                    outWidth = originalWidth / 2;
                    outHeight = originalHeight / 2;
                    bitrate = (outWidth/2) * (outHeight/2) * 10;
                    break;
            }
//            bitrate = bitrate / 2;
//            if(bitrate>originalBitrate){
//                bitrate = originalBitrate*3/4;
//            }
            if(outWidth != originalWidth||outHeight != originalHeight||bitrate != originalBitrate){
                VideoProcessor.Processor processor = VideoProcessor.processor(context)
                        .input(localPah)
                        .output(outputVideoPath)
                        .outWidth(outWidth)
                        .outHeight(outHeight)
                        .bitrate(bitrate);
                if(listener!=null){
                    processor.progressListener(listener);
                }
                processor.process();
            }else{
                outputVideoPath = localPah;
            }
        }catch (Exception e){
            if(videoParam!=null){
                outWidth = videoParam.getWidth();
                outHeight = videoParam.getHeight();
            }
            outputVideoPath = localPah;
        }
//        outputVideoPath = localPah;
        return newVideo(outputVideoPath,outWidth,outHeight,videoParam==null?1000:videoParam.getDuration());
    }
}
